﻿using Pathfinding;
using UnityEngine;
using Yoozoo.Mars.Got;

namespace Yoozoo.Gameplay.City
{
    public class CityRoomNpcController : CityRealAiNpcController
    {
        public override CityRealNpcType NpcType
        {
            get { return CityRealNpcType.RoomNpc; }
        }
        
        public CityRoomNpcController(int birthContainerId, CityRealAiRoleInfoConfig roleInfoConfig, Vector3 birthWorldPos) : base(birthContainerId, roleInfoConfig, birthWorldPos)
        {
        }
        
        protected override void LoadRoleObjComplete()
        {
            base.LoadRoleObjComplete();
            _roleObj.SetLayerRecursively(LayerMask.NameToLayer("LOD1_2"));
            var ins = CityRealAiManager.GetInstance();
            if(model)
                model.SetCullingLayer(ins.RoofShowState && ins.LimitShowState? CityRealAiConst.NpcHideLayerMask : CityRealAiConst.NpcShowLayerMask);
            Seeker.SetIsInRoomAction(true);
            UpdateSunLight(false);
            if (RoleTag == CityRealAiConst.TransportNpcTag || RoleTag == CityRealAiConst.UpgradeNpcTag)
            {
                Seeker.SetupStartEndExactnessType(StartEndModifier.Exactness.Original);
            }
            else
            {
                Seeker.SetupStartEndExactnessType(StartEndModifier.Exactness.SnapToNode);
            }
            
            if (_containerMgr is CityRealAiRoomManager room)
            {
                if (ServerRoleInfo.isShow) // 默认是否显示
                {
                    Seeker.UpdatePos(room.GetWorldPos(room.GetRandomBirthLocalPos()));
                    if (_delayFirstStartTime <= 0)
                    {
                        _delayFirstStartTime = 0.001f;
                    }
                    Timers.inst.Add(_delayFirstStartTime, 1, (o) =>
                    {
                        if (TreeConfig.event_tree_id != _cfgMgr.EmptyEventTreeCfg.event_tree_id && TreeType == CityRealEventTreeType.SpecialEventTree)
                        {
                            ExecuteEventTreePosition();
                        }
                        else
                        {
                            TryExecuteEventTree();
                        }
                    });
                }
                else
                {
                    Seeker.UpdatePos(room.GetWorldPos(room.HidePointLocalPos));
                    _roleObj.SetActive(false);
                }
            }
        }
        
        protected override void SearchPathPartialComplete()
        {
            if (RoleTag == CityRealAiConst.UpgradeNpcTag ||
                RoleTag == CityRealAiConst.TransportNpcTag) // 如果是升级小人被围追堵截了，表现也还是会比较奇怪，因为他要去执行的是房间事件
            {
                if (_containerMgr is CityRealAiAreaManager)
                {
                    var excludeRoomId = 0;
                    if (_moveToRoom != null)
                    {
                        excludeRoomId = _moveToRoom.ContainerId;
                    }
                    EndEventTree();
                    TryExecuteEventTree(excludeRoomId);
                }
                else if (_containerMgr is CityRealAiRoomManager roomMgr)
                {
                    // 理论上，在房间内不应该可以寻路失败，给他重置一下位置，再重新寻找一个可执行的事件
                    Seeker.UpdatePos(roomMgr.GetWorldPos(roomMgr.GetRandomBirthLocalPos()));
                    EndEventTree();
                    TryExecuteEventTree();
                }
            }
            // 其他类型的房间小人不会出房间
        }

        protected override void SearchPathErrorComplete()
        {
            if (RoleTag == CityRealAiConst.UpgradeNpcTag ||
                RoleTag == CityRealAiConst.TransportNpcTag) // 无处可逃，
            {
                if (_containerMgr is CityRealAiAreaManager)
                {
                    var treeArray = RoleConfig.faulttolerance_tree_array;
            
                    var totalWeight = 0f;
                    for (int i = 0; i < treeArray.Length; i++)
                    {
                        var treeCfg = treeArray[i];
                        totalWeight += treeCfg.y;
                    }

                    var executeTreeCfg = Vector2.zero;
                    int cursor = 0;
                    int random = Random.Range(0, (int) totalWeight);
                    for (int i = 0; i < treeArray.Length; i++)
                    {
                        var treeCfg = treeArray[i];
                        cursor += (int) treeCfg.y;
                        if(cursor > random)
                        {
                            executeTreeCfg = treeCfg;
                            break;
                        }
                    }

                    TreeConfig = _cfgMgr.GetAiEventTreeConfig((int)executeTreeCfg.x);
                    TreeState = CityRealEventTreeState.WaitMoveRoom;
                    TreeType = CityRealEventTreeType.SerarchPathFailedEventTree;
                    TreeIsInterrupt = TreeConfig.is_interrupt;
                    ExecuteEventTreePosition();
                }
                // 理论上，在房间内不应该可以寻路失败，但是他竟然在房间内，重置位置还多次寻路失败，这只能怀疑寻路有问题了。
            }
            // 其他类型的房间小人不会出房间
        }
        
    }
}
